package handlers

import (
	"net/http"

	"github.com/gin-gonic/gin"

	"github.com/samaa/photosalesplus/backend/internal/services"
)

type AuthHandler struct {
	authService services.AuthService
	userService services.UserService
}

func NewAuthHandler(authService services.AuthService, userService services.UserService) *AuthHandler {
	return &AuthHandler{authService: authService, userService: userService}
}

type registerRequest struct {
	Username    string `json:"username" binding:"required,min=3,max=32"`
	Password    string `json:"password" binding:"required,min=6,max=64"`
	DisplayName string `json:"display_name"`
	Email       string `json:"email"`
}

type loginRequest struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
}

type updateProfileRequest struct {
	DisplayName *string `json:"display_name"`
	AvatarURL   *string `json:"avatar_url"`
}

func (h *AuthHandler) Register(c *gin.Context) {
	var req registerRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: err.Error()})
		return
	}

	user, err := h.userService.Register(
		c.Request.Context(),
		req.Username,
		req.Password,
		req.DisplayName,
		req.Email,
	)
	if err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: err.Error()})
		return
	}

	respondCreated(c, h.userService.Sanitize(user))
}

func (h *AuthHandler) Login(c *gin.Context) {
	var req loginRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: err.Error()})
		return
	}

	token, user, err := h.authService.Login(c.Request.Context(), req.Username, req.Password)
	if err != nil {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: err.Error()})
		return
	}

	respondSuccess(c, gin.H{
		"token": token,
		"user":  h.userService.Sanitize(user),
	}, nil)
}

func (h *AuthHandler) Logout(c *gin.Context) {
	token := c.GetString("token")
	_ = h.authService.Logout(c.Request.Context(), token)
	c.JSON(http.StatusOK, APIResponse{Message: "已退出登录"})
}

func (h *AuthHandler) DeleteAccount(c *gin.Context) {
	val, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	userID, ok := val.(uint)
	if !ok {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	if err := h.userService.Delete(c.Request.Context(), userID); err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}

	token := c.GetString("token")
	_ = h.authService.Logout(c.Request.Context(), token)

	c.JSON(http.StatusOK, APIResponse{Message: "账号已注销"})
}

func (h *AuthHandler) UpdateProfile(c *gin.Context) {
	var req updateProfileRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: err.Error()})
		return
	}

	if req.DisplayName == nil && req.AvatarURL == nil {
		c.JSON(http.StatusBadRequest, APIResponse{Error: "缺少需要更新的内容"})
		return
	}

	val, exists := c.Get("user_id")
	if !exists {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	userID, ok := val.(uint)
	if !ok || userID == 0 {
		c.JSON(http.StatusUnauthorized, APIResponse{Error: "未授权"})
		return
	}

	updated, err := h.userService.UpdateProfile(c.Request.Context(), userID, req.DisplayName, req.AvatarURL)
	if err != nil {
		respondError(c, http.StatusInternalServerError, err)
		return
	}

	respondSuccess(c, h.userService.Sanitize(updated), nil)
}
